package com.dctp.common.utils;

import java.lang.reflect.Field;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * Map 工具类（支持泛型、链式操作、空安全）
 */
public final class MapUtil {

    private MapUtil() {
        throw new UnsupportedOperationException("MapUtil is a utility class and cannot be instantiated");
    }

    // ---------------------- 基础工具 ----------------------

    /**
     * 判断 Map 是否为空
     */
    public static boolean isEmpty(Map<?, ?> map) {
        return map == null || map.isEmpty();
    }

    /**
     * 判断 Map 非空
     */
    public static boolean isNotEmpty(Map<?, ?> map) {
        return !isEmpty(map);
    }

    // ---------------------- 创建与初始化 ----------------------

    /**
     * 创建不可变 Map（JDK9+风格，兼容JDK8）
     */
    @SafeVarargs
    public static <K, V> Map<K, V> ofImmutable(Map.Entry<K, V>... entries) {
        if (entries == null || entries.length == 0)
            return Collections.emptyMap();
        Map<K, V> map = new LinkedHashMap<>();
        for (Map.Entry<K, V> entry : entries) {
            map.put(entry.getKey(), entry.getValue());
        }
        return Collections.unmodifiableMap(map);
    }

    /**
     * 快速构建 Entry（配合 ofImmutable 使用）
     */
    public static <K, V> Map.Entry<K, V> entry(K key, V value) {
        return new AbstractMap.SimpleEntry<>(key, value);
    }

    // ---------------------- 安全获取与转换 ----------------------

    /**
     * 安全获取值（避免 NPE）
     * 
     * @param defaultValue 当值为 null 或类型不匹配时的默认值
     */
    @SuppressWarnings("unchecked")
    public static <T> T safeGet(Map<?, ?> map, Object key, T defaultValue) {
        if (isEmpty(map))
            return defaultValue;
        Object value = map.get(key);
        try {
            return (T) value;
        } catch (ClassCastException e) {
            return defaultValue;
        }
    }

    /**
     * 将 Map 转换为 Properties 对象
     */
    public static Properties toProperties(Map<String, String> map) {
        Properties props = new Properties();
        if (isNotEmpty(map)) {
            props.putAll(map);
        }
        return props;
    }

    // ---------------------- 集合操作 ----------------------

    /**
     * 过滤 Map 条目
     * 
     * @param predicate 过滤条件（如 entry -> entry.getValue() > 100）
     */
    public static <K, V> Map<K, V> filter(Map<K, V> map, Predicate<Map.Entry<K, V>> predicate) {
        if (isEmpty(map))
            return Collections.emptyMap();
        return map.entrySet().stream()
                .filter(predicate)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    }

    // ---------------------- 类型转换 ----------------------

    /**
     * 转换 Map 的键类型
     * 
     * @param keyMapper 键转换函数（如 String::toLowerCase）
     */
    public static <K1, K2, V> Map<K2, V> mapKeys(Map<K1, V> map, Function<K1, K2> keyMapper) {
        if (isEmpty(map))
            return Collections.emptyMap();
        return map.entrySet().stream()
                .collect(Collectors.toMap(
                        e -> keyMapper.apply(e.getKey()),
                        Map.Entry::getValue,
                        (oldVal, newVal) -> newVal));
    }

    /**
     * 转换 Map 的值类型
     * 
     * @param valueMapper 值转换函数（如 Integer::parseInt）
     */
    public static <K, V1, V2> Map<K, V2> mapValues(Map<K, V1> map, Function<V1, V2> valueMapper) {
        if (isEmpty(map))
            return Collections.emptyMap();
        return map.entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        e -> valueMapper.apply(e.getValue())));
    }

    // ---------------------- 排序 ----------------------

    /**
     * 按键排序（自然顺序）
     */
    public static <K extends Comparable<? super K>, V> Map<K, V> sortByKey(Map<K, V> map) {
        if (isEmpty(map))
            return Collections.emptyMap();
        return map.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (oldVal, newVal) -> oldVal,
                        LinkedHashMap::new));
    }

    /**
     * 按值排序（自然顺序）
     */
    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
        if (isEmpty(map))
            return Collections.emptyMap();
        return map.entrySet().stream()
                .sorted(Map.Entry.comparingByValue())
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (oldVal, newVal) -> oldVal,
                        LinkedHashMap::new));
    }

    public static Map<String, Object> toSnakeCaseMap(Object obj) {
        Map<String, Object> result = new HashMap<>();
        if (obj == null)
            return result;

        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                String snakeName = field.getName()
                        .replaceAll("([a-z])([A-Z])", "$1_$2")
                        .toLowerCase();
                result.put(snakeName, field.get(obj));
            } catch (IllegalAccessException ignored) {
            }
        }
        return result;
    }
}